﻿using CounterServerModel.Exceptions;
using System.Data;

namespace CounterServerModel.Authentication
{
    /// <summary>
    /// A class for authentication against the server.
    /// </summary>
    public class AuthenticationService
    {
        /// <summary>
        /// Checks in the database if the credentials are correct, and if they are correct returns an AuthenticatedUserCredentials object that contains the internal ID of the user
        /// and the users password. Otherwise returns null. The user will send this ID instead of its username in next requests to make the search more efficient.
        /// </summary>
        /// <param name="i_UserCredentials">The credentials of the user we want to check.</param>
        /// <returns>
        /// If the credentials are correct returns an AuthenticatedUserCredentials object that contains the internal ID of the user and the user's password.
        /// Otherwise returns null.
        /// </returns>
        public AuthenticatedUserCredentials Authenticate(UserCredentials i_UserCredentials)
        {
            DataTable table = DBService.Instance.PerformQuery(string.Format("SELECT UserID, Password FROM Users WHERE Username = '{0}'", i_UserCredentials.Username));

            if (table.Rows.Count == 0)
            {
                return null;
            }

            if (table.Rows.Count > 1)
            {
                throw new MultipleUsernameException(i_UserCredentials.Username);
            }

            if (table.Rows[0]["Password"].ToString() != i_UserCredentials.Password)
            {
                return null;
            }

            return new AuthenticatedUserCredentials(int.Parse(table.Rows[0]["UserID"].ToString()), i_UserCredentials.Password);
        }

        /// <summary>
        /// Validates that the password is correct for the given User ID.
        /// </summary>
        /// <param name="i_AuthenticatedUserCredentials">User's credentials.</param>
        public void ValidateAuthentication(AuthenticatedUserCredentials i_AuthenticatedUserCredentials)
        {
            DataTable table = DBService.Instance.PerformQuery(string.Format("SELECT Password FROM Users WHERE UserID = '{0}'", i_AuthenticatedUserCredentials.ID));

            if (table.Rows.Count == 0)
            {
                throw new UserIDNotExistsException(i_AuthenticatedUserCredentials.ID);
            }

            if (table.Rows[0]["Password"].ToString() != i_AuthenticatedUserCredentials.Password)
            {
                throw new PasswordValidationFailedException(i_AuthenticatedUserCredentials);
            }
        }
    }
}
